<?php
/**
 * Nordic Repository
 * 
 * LICENSE
 * 
 * The new BSD license is applied on this source-file. For further
 * information please visit http://license.nordic-dev.de/newbsd.txt
 * or send an email to andre.moelle@gmail.com.
 */

/**
 * Necessary includes.
 */
require_once 'Nordic/Pagebar.php';
require_once 'Nordic/Pagebar/Element.php';

/**
 * Abstract behaviour.
 * 
 * @category   Nordic
 * @package    Nordic_Pagebar
 * @copyright  2007 Nordic Development
 * @license    http://license.nordic-dev.de/newbsd.txt (New-BSD license)
 * @author     Andre Moelle <andre.moelle@gmail.com>
 * @version    $Id: Behaviour.php 3 2007-07-08 09:21:42Z andre.moelle $
 */
abstract class Nordic_Pagebar_Behaviour
{
	/**
	 * Optional additional behaviour.
	 * 
	 * @var Nordic_Pagebar_Behaviour
	 */
	protected $_behaviour = null;
	
	/**
	 * Exponent to the base 2.
	 * 
	 * @var integer
	 */
	private $_exponent = 0;
	
	/**
	 * Value calculated by the _exponent to the base 2.
	 * 
	 * @var integer
	 */
	protected $_value = 1;
	
	/**
	 * Returns true if the page fulfills this behaviour.
	 * 
	 * @param Nordic_Pagebar $pagebar pagebar
	 * @param integer $page active page in iteration
	 * @return boolean
	 */
	abstract protected function _applies (Nordic_Pagebar $pagebar, $page);
	
	/**
	 * Method which checks if an integer contains or is the type.
	 * 
	 * The strict-parameter determines if the given integer should be
	 * equal to the type or if the type should only contain the given
	 * integer.
	 * 
	 * @param integer $type type of the element
	 * @param boolean $strict strict check
	 * @return boolean
	 */
	protected function _compare ($type, $strict = false)
	{
		if(!$strict)
		{
			return (($this->getValue() & $type) == $this->getValue());
		}
		
		return ($this->getValue() == $type);
	}
	
	/**
	 * The method returns the type of the given page.
	 * 
	 * Additionally the method calls the given behaviour when
	 * there was one set. If no behaviour fits, 0 is returned.
	 * 
	 * @param Nordic_Pagebar $pagebar pagebar
	 * @param integer $page active page in iteration
	 * @return integer
	 */
	public function applies (Nordic_Pagebar $pagebar, $page)
	{
		$result = 0;
		
		if($this->_applies($pagebar, $page))
		{
			$result |= $this->getValue();
		}
		
		if($this->_behaviour != null)
		{
			$result |= $this->_behaviour->applies($pagebar, $page);
		}
		
		return $result;
	}
	
	/**
	 * Adds new behaviour to this behaviour.
	 * 
	 * @param Nordic_Pagebar_Behaviour $behaviour new behaviour
	 * @return void
	 */
	public function behave (Nordic_Pagebar_Behaviour $behaviour)
	{
		$this->_behaviour = $behaviour;
		$this->_exponent = null;
	}
	
	/**
	 * Returns the alias of the behaviour.
	 * 
	 * @param void
	 * @return string
	 */
	abstract public function getAlias ();
	
	/**
	 * @see Nordic_Pagebar_Behaviour::_value
	 */
	public function getValue ()
	{
		if($this->_exponent == null)
		{
			$this->setExponent();
		}
		
		return $this->_value;
	}
	
	/**
	 * Returns true if this behaviour or another decorated is true.
	 * 
	 * Otherwise false is returned.
	 * 
	 * @param string $alias alias of the behaviour to check
	 * @param Nordic_Pagebar_Element $element that should be checked
	 * @param boolean $strict strict check
	 */
	public function is ($alias, Nordic_Pagebar_Element $element, $strict = false)
	{
		if($this->getAlias() == $alias)
		{
			return $this->_compare($element->getType(), $strict);
		}
		else if($this->_behaviour == null)
		{
			return false;
		}
		
		return $this->_behaviour->is($alias, $element, $strict);
	}
	
	/**
	 * Sets a new exponent.
	 * 
	 * @param integer $exponent new exponent
	 * @return void
	 */
	public function setExponent ()
	{
		if($this->_behaviour == null)
		{
			$this->_exponent = 0;
		}
		else
		{
			$this->_exponent = $this->_behaviour->setExponent() + 1;
		}
		
		$this->_value = pow(2, $this->_exponent);
		
		return $this->_exponent;
	}
}
?>